Quick Info
Coyotes (Canis lantrans) data on three individuals near Albany, NY, during the spring and summer of 2001, were used as examples for performing home range analyses.
Data comes from:
Bogan, D.A. 2004 Eastern coyote (Canis latrans) home range, habitat selection, and survival rates in the suburban Albany Pine Bush landscape of New York. MA Thesis. State University of New York at Albany.

Dataset
Convert Lat & Long to UTM Because I’m stubborn
Lets see if the dataset has any outliers, and get a rough view of the locations in a map.
Here, I will do a quick map on the three coyote individuals with a basemap from Open Street Map.
utm_points <- cbind(coyote$utm.easting, coyote$utm.northing)
utm_locations <- SpatialPoints(utm_points,
proj4string=CRS("+proj=utm +zone=18 +datum=WGS84"))
proj_lat.lon <- as.data.frame(spTransform(
utm_locations, CRS("+proj=longlat +datum=WGS84")))
colnames(proj_lat.lon) <- c("x","y")
raster <- openmap(c(max(proj_lat.lon$y)+0.01, min(proj_lat.lon$x)-0.01),
c(min(proj_lat.lon$y)-0.01, max(proj_lat.lon$x)+0.01),
type = "bing")
raster_utm <- openproj(raster,
projection = "+proj=utm +zone=18 +ellps=WGS84 +units=m +no_defs")
autoplot(raster_utm, expand = TRUE) + theme_bw() +
theme(legend.position="bottom") +
theme(panel.border = element_rect(colour = "black", fill=NA, size=1)) +
geom_point(data=coyote, aes(utm.easting,utm.northing,
color=individual.local.identifier), size = 3, alpha = 0.8) +
theme(axis.title = element_text(face="bold")) + labs(x="Easting",
y="Northing") + guides(color=guide_legend("Identifier"))

Both Beta and Omega had overlaping locations.
Home Range Analysis
Three basic types of home range analyses we will perform in this exercise: Minimum Convex Polygon (MCP), Kernel-Density Estimation (KDE), and Brownian Bridge Movement Model (BB).
MCP - draws the smallest polygon around points with all interior angles less than 180 degrees. MCPs are common estimators of home range, but can potentially include area not used by the animal and overestimate the home range
KDE - calculates the density of features in a neighborhood around those features.
BB - models movement of an individual
MCP Analysis
mcp_raster <- function(filename){
data <- read.csv(file = filename)
x <- as.data.frame(data$utm.easting)
y <- as.data.frame(data$utm.northing)
xy <- c(x,y)
data.proj <- SpatialPointsDataFrame(xy,data, proj4string = CRS("+proj=utm +zone=18 +ellps=WGS84 +units=m +no_defs"))
xy <- SpatialPoints(data.proj@coords)
mcp.out <- mcp(xy, percent=100, unout="ha")
mcp.points <- cbind((data.frame(xy)),data$individual.local.identifier)
colnames(mcp.points) <- c("x","y", "identifier")
mcp.poly <- fortify(mcp.out, region = "id")
units <- grid.text(paste(round(mcp.out@data$area,2),"ha"), x=0.85, y=0.95,
gp=gpar(fontface=4, col="white", cex=0.9), draw = FALSE)
mcp.plot <- autoplot(raster_utm, expand = TRUE) + theme_bw() + theme(legend.position="none") +
theme(panel.border = element_rect(colour = "black", fill=NA, size=1)) +
geom_polygon(data=mcp.poly, aes(x=mcp.poly$long, y=mcp.poly$lat), alpha=0.8) +
geom_point(data=mcp.points, aes(x=x, y=y)) +
labs(x="Easting (m)", y="Northing (m)", title=mcp.points$identifier) +
theme(legend.position="none", plot.title = element_text(face = "bold", hjust = 0.5)) +
annotation_custom(units)
mcp.plot
}
pblapply(files, mcp_raster)
| | 0 % ~calculating
|======================================= | 33% ~01s
|============================================================================== | 67% ~00s
|====================================================================================================================| 100% elapsed=01s
[[1]]
[[2]]
[[3]]



Kernel-Density Estimation
kde_raster <- function(filename){
data <- read.csv(file = filename)
x <- as.data.frame(data$utm.easting)
y <- as.data.frame(data$utm.northing)
xy <- c(x,y)
data.proj <- SpatialPointsDataFrame(xy,data, proj4string = CRS("+proj=utm +zone=18 +ellps=WGS84 +units=m +no_defs"))
xy <- SpatialPoints(data.proj@coords)
kde<-kernelUD(xy, h="href", kern="bivnorm", grid=100)
ver <- getverticeshr(kde, 95)
kde.points <- cbind((data.frame(data.proj@coords)),data$individual.local.identifier)
colnames(kde.points) <- c("x","y","identifier")
kde.poly <- fortify(ver, region = "id")
units <- grid.text(paste(round(ver$area,2)," ha"), x=0.85, y=0.95,
gp=gpar(fontface=4, col="white", cex=0.9), draw = FALSE)
kde.plot <- autoplot(raster_utm, expand = TRUE) + theme_bw() + theme(legend.position="none") +
theme(panel.border = element_rect(colour = "black", fill=NA, size=1)) +
geom_polygon(data=kde.poly, aes(x=kde.poly$long, y=kde.poly$lat), alpha = 0.8) +
geom_point(data=kde.points, aes(x=x, y=y)) +
labs(x="Easting (m)", y="Northing (m)", title=kde.points$identifier) +
theme(legend.position="none", plot.title = element_text(face = "bold", hjust = 0.5)) +
annotation_custom(units)
kde.plot
}
pblapply(files, kde_raster)
| | 0 % ~calculating
|======================================= | 33% ~01s
|============================================================================== | 67% ~00s
|====================================================================================================================| 100% elapsed=01s
[[1]]
[[2]]
[[3]]



Brownian Bridge Movement
No Luck for Now;
couldn’t get crop to run message was: “Error in x@coords[i, , drop = FALSE] : subscript out of bounds”
However, I learned that in excel you need to set the format of the column to custum and type in “yyyy-mm-dd h:mm:ss” and it will correct the entire column to that format. This may be very much a no brainer.
Animate Trajectory Data
Here is my attempt at creating an animation of the individual “Alpha”’s movement from April to July in 2001 in Albany, NY, USA. Data was collected by radio telemetry.
A.move <- move(x=A$location.long,
y=A$location.lat,
time=as.POSIXct(A$timestamp,
format="%Y-%m-%d %H:%M:%S", tz="Asia/Bangkok"),
proj=CRS("+proj=longlat +ellps=WGS84 +datum=WGS84"),
data=A, animal=A$individual.local.identifier,
sensor=A$sensor.type)
movement <- align_move(A.move, res = "max", digit = 0, unit = "secs")
frames <- frames_spatial(movement, path_colours = "orange",
map_service = "osm",
alpha = 0.5) %>%
add_labels(x = "Longitude", y = "Latitude") %>%
add_northarrow() %>%
add_scalebar() %>%
add_timestamps(movement, type = "label") %>%
add_progress()
animate_frames(frames, fps = 5, overwrite = TRUE,
out_file = "./moveVis-5fps.gif")

LS0tDQp0aXRsZTogIkhvbWUgUmFuZ2UgQ3Jhc2ggQ291cnNlIg0KYXV0aG9yOiAiSmFjayBLYXVwaHVzbWFuIg0KZGF0ZTogIjExLzEzLzIwMTkiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6DQogICAgZGZfcHJpbnQ6IHBhZ2VkDQogICAgaGlnaGxpZ2h0OiBicmVlemVkYXJrDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICByb3dzLnByaW50OiAxMA0KICAgIHRoZW1lOiBjb3Ntbw0KICAgIHRvYzogeWVzDQogICAgdG9jX2Zsb2F0Og0KICAgICAgY29sbGFwc2VkOiBubw0KICAgICAgc21vb3RoX3Njcm9sbDogeWVzDQogIGh0bWxfZG9jdW1lbnQ6DQogICAgZGZfcHJpbnQ6IHBhZ2VkDQogICAgdG9jOiB5ZXMNCiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0DQplZGl0b3Jfb3B0aW9uczoNCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQ0KLS0tDQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KDQpoMS50aXRsZSB7DQogIGZvbnQtc2l6ZTogNDBweDsNCiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogIGNvbG9yOiBEYXJrQmx1ZTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDQuYXV0aG9yIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAyMHB4Ow0KICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgY29sb3I6IERhcmtCbHVlOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQo8L3N0eWxlPg0KLS0tDQoNCmBgYHtyIFBhY2thZ2VzLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0KcGFja2FnZXM8LWMoImFkZWhhYml0YXRIUiIsImRhdGEudGFibGUiLCJnZ2ZvcnRpZnkiLCJncmlkIiwibW92ZSIsIm1vdmVWaXMiLCJPcGVuU3RyZWV0TWFwIiwicGJhcHBseSIsInBsb3RseSIsInJnZGFsIiwic3AiLCJ0aWR5dmVyc2UiLCJ2aXJpZGlzIikNCnNhcHBseShwYWNrYWdlcywgcmVxdWlyZSwgY2hhcmFjdGVyLm9ubHk9VCkNCmxpYnJhcnkockphdmEpDQpsaWJyYXJ5KE9wZW5TdHJlZXRNYXApDQpsaWJyYXJ5IChyYXN0ZXIpDQpgYGANCiMgUXVpY2sgSW5mbw0KDQpDb3lvdGVzICgqQ2FuaXMgbGFudHJhbnMqKSBkYXRhIG9uIHRocmVlIGluZGl2aWR1YWxzIG5lYXIgQWxiYW55LCBOWSwgZHVyaW5nIHRoZSBzcHJpbmcgYW5kIHN1bW1lciBvZiAyMDAxLCB3ZXJlIHVzZWQgYXMgZXhhbXBsZXMgZm9yIHBlcmZvcm1pbmcgaG9tZSByYW5nZSBhbmFseXNlcy4NCg0KRGF0YSBjb21lcyBmcm9tOg0KDQpCb2dhbiwgRC5BLiAyMDA0IEVhc3Rlcm4gY295b3RlIChDYW5pcyBsYXRyYW5zKSBob21lIHJhbmdlLCBoYWJpdGF0IHNlbGVjdGlvbiwgYW5kIHN1cnZpdmFsIHJhdGVzIGluIHRoZSBzdWJ1cmJhbiBBbGJhbnkgUGluZSBCdXNoIGxhbmRzY2FwZSBvZiBOZXcgWW9yay4gTUEgVGhlc2lzLiBTdGF0ZSBVbml2ZXJzaXR5IG9mIE5ldyBZb3JrIGF0IEFsYmFueS4NCg0KDQohW10oZGF0YS9pbWFnZS5qcGcpIA0KDQoNCiMgRGF0YXNldCANCmBgYHtyfQ0KY295b3RlPC1yZWFkLmNzdigiZGF0YS9jb3lvdGUuY3N2IikNCmhlYWQoY295b3RlKQ0KYGBgDQoNCkNvbnZlcnQgTGF0ICYgTG9uZyB0byBVVE0gQmVjYXVzZSBJJ20gc3R1YmJvcm4NCg0KYGBge3J9DQp6b25lMTg8LWRhdGEuZnJhbWUoY295b3RlJGxvY2F0aW9uLmxvbmcsIGNveW90ZSRsb2NhdGlvbi5sYXQpDQpuYW1lcyh6b25lMTgpPC1jKCJYIiwgIlkiKQ0Kem9uZTE4PC1hcy5tYXRyaXgoem9uZTE4KQ0KVVRNPC1wcm9qZWN0KHpvbmUxOCwgIitwcm9qPXV0bSArem9uZT0xOCBlbGxwcz1XR1M4NCIpDQpVVE08LWRhdGEuZnJhbWUoVVRNKQ0KbmFtZXMoVVRNKTwtYygidXRtLmVhc3RpbmciLCAidXRtLm5vcnRoaW5nIikNCmNveW90ZTwtY2JpbmQoY295b3RlLCBVVE0pDQpgYGANCg0KDQpMZXRzIHNlZSBpZiB0aGUgZGF0YXNldCBoYXMgYW55IG91dGxpZXJzLCBhbmQgZ2V0IGEgcm91Z2ggdmlldyBvZiB0aGUgbG9jYXRpb25zIGluIGEgbWFwLg0KDQpgYGB7cn0NCm1hcDEgPC0gZ2dwbG90KCkgKyBnZW9tX3BvaW50KGRhdGE9Y295b3RlLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWVzKHV0bS5lYXN0aW5nLCB1dG0ubm9ydGhpbmcsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvcj1pbmRpdmlkdWFsLmxvY2FsLmlkZW50aWZpZXIpKSArDQogICAgICAgICAgICAgICAgICAgICAgICBsYWJzKHg9IkVhc3RpbmciLCB5PSAiTm9ydGhpbmciKSArDQogICAgICAgICAgICAgICAgICAgICAgICBndWlkZXMoY29sb3I9Z3VpZGVfbGVnZW5kKCJJZGVudGlmaWVyIikpDQoNCmdncGxvdGx5KG1hcDEpDQoNCmBgYA0KSGVyZSwgSSB3aWxsIGRvIGEgcXVpY2sgbWFwIG9uIHRoZSB0aHJlZSBjb3lvdGUgaW5kaXZpZHVhbHMgd2l0aCBhIGJhc2VtYXAgZnJvbSBPcGVuIFN0cmVldCBNYXAuIA0KDQpgYGB7ciBpbWFnZXJ5LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPVRSVUUsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTh9DQp1dG1fcG9pbnRzIDwtIGNiaW5kKGNveW90ZSR1dG0uZWFzdGluZywgY295b3RlJHV0bS5ub3J0aGluZykNCnV0bV9sb2NhdGlvbnMgPC0gU3BhdGlhbFBvaW50cyh1dG1fcG9pbnRzLCANCiAgICAgICAgICAgICAgICAgcHJvajRzdHJpbmc9Q1JTKCIrcHJvaj11dG0gK3pvbmU9MTggK2RhdHVtPVdHUzg0IikpDQpwcm9qX2xhdC5sb24gPC0gYXMuZGF0YS5mcmFtZShzcFRyYW5zZm9ybSgNCiAgICAgICAgICAgICAgICB1dG1fbG9jYXRpb25zLCBDUlMoIitwcm9qPWxvbmdsYXQgK2RhdHVtPVdHUzg0IikpKQ0KY29sbmFtZXMocHJval9sYXQubG9uKSA8LSBjKCJ4IiwieSIpDQpyYXN0ZXIgPC0gb3Blbm1hcChjKG1heChwcm9qX2xhdC5sb24keSkrMC4wMSwgbWluKHByb2pfbGF0LmxvbiR4KS0wLjAxKSwgDQogICAgICAgICAgICAgICAgICBjKG1pbihwcm9qX2xhdC5sb24keSktMC4wMSwgbWF4KHByb2pfbGF0LmxvbiR4KSswLjAxKSwgDQogICAgICAgICAgICAgICAgICB0eXBlID0gImJpbmciKQ0KcmFzdGVyX3V0bSA8LSBvcGVucHJvaihyYXN0ZXIsIA0KICAgICAgICAgICAgICBwcm9qZWN0aW9uID0gIitwcm9qPXV0bSArem9uZT0xOCArZWxscHM9V0dTODQgK3VuaXRzPW0gK25vX2RlZnMiKQ0KDQoNCmF1dG9wbG90KHJhc3Rlcl91dG0sIGV4cGFuZCA9IFRSVUUpICsgdGhlbWVfYncoKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIikgKw0KICB0aGVtZShwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoY29sb3VyID0gImJsYWNrIiwgZmlsbD1OQSwgc2l6ZT0xKSkgKw0KICBnZW9tX3BvaW50KGRhdGE9Y295b3RlLCBhZXModXRtLmVhc3RpbmcsdXRtLm5vcnRoaW5nLA0KICAgICAgICAgICAgIGNvbG9yPWluZGl2aWR1YWwubG9jYWwuaWRlbnRpZmllciksIHNpemUgPSAzLCBhbHBoYSA9IDAuOCkgKw0KICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2U9ImJvbGQiKSkgKyBsYWJzKHg9IkVhc3RpbmciLA0KICAgICAgICB5PSJOb3J0aGluZyIpICsgZ3VpZGVzKGNvbG9yPWd1aWRlX2xlZ2VuZCgiSWRlbnRpZmllciIpKQ0KYGBgDQpCb3RoIEJldGEgYW5kIE9tZWdhIGhhZCBvdmVybGFwaW5nIGxvY2F0aW9ucy4NCg0KDQpgYGB7ciBsYXBwbHkgZnVuY3Rpb24sIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0UsIHJlc3VsdHM9J2hpZGUnfQ0KbGFwcGx5KHNwbGl0KGNveW90ZSwgY295b3RlJGluZGl2aWR1YWwubG9jYWwuaWRlbnRpZmllciksIA0KICAgICAgIGZ1bmN0aW9uKHgpd3JpdGUuY3N2KHgsIGZpbGUgPSBwYXN0ZSh4JGluZGl2aWR1YWwubG9jYWwuaWRlbnRpZmllclsxXSwiLmNzdiIpLCByb3cubmFtZXMgPSBGQUxTRSkpDQpgYGANCg0KYGBge3IgbGlzdCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZWNobz1UUlVFLCByZXN1bHRzPSdoaWRlJ30NCmZpbGVzIDwtIGxpc3QuZmlsZXMocGF0aCA9ICIuIiwgcGF0dGVybiA9IiouY3N2IiAsIGZ1bGwubmFtZXMgPSBUUlVFKQ0KYGBgDQoNCiMgSG9tZSBSYW5nZSBBbmFseXNpcw0KDQpUaHJlZSBiYXNpYyB0eXBlcyBvZiBob21lIHJhbmdlIGFuYWx5c2VzIHdlIHdpbGwgcGVyZm9ybSBpbiB0aGlzIGV4ZXJjaXNlOiBNaW5pbXVtIENvbnZleCBQb2x5Z29uIChNQ1ApLCBLZXJuZWwtRGVuc2l0eSBFc3RpbWF0aW9uIChLREUpLCBhbmQgQnJvd25pYW4gQnJpZGdlIE1vdmVtZW50IE1vZGVsIChCQikuDQoNCk1DUCAtIGRyYXdzIHRoZSBzbWFsbGVzdCBwb2x5Z29uIGFyb3VuZCBwb2ludHMgd2l0aCBhbGwgaW50ZXJpb3IgYW5nbGVzIGxlc3MgdGhhbiAxODAgZGVncmVlcy4gTUNQcyBhcmUgY29tbW9uIGVzdGltYXRvcnMgb2YgaG9tZSByYW5nZSwgYnV0IGNhbiBwb3RlbnRpYWxseSBpbmNsdWRlIGFyZWEgbm90IHVzZWQgYnkgdGhlIGFuaW1hbCBhbmQgb3ZlcmVzdGltYXRlIHRoZSBob21lIHJhbmdlDQoNCktERSAtIGNhbGN1bGF0ZXMgdGhlIGRlbnNpdHkgb2YgZmVhdHVyZXMgaW4gYSBuZWlnaGJvcmhvb2QgYXJvdW5kIHRob3NlIGZlYXR1cmVzLg0KDQpCQiAtIG1vZGVscyBtb3ZlbWVudCBvZiBhbiBpbmRpdmlkdWFsDQoNCiMjIE1DUCBBbmFseXNpcw0KDQpgYGB7ciBNQ1AgcGxvdCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZWNobz1UUlVFLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD02fQ0KbWNwX3Jhc3RlciA8LSBmdW5jdGlvbihmaWxlbmFtZSl7DQogIGRhdGEgPC0gcmVhZC5jc3YoZmlsZSA9IGZpbGVuYW1lKQ0KICB4IDwtIGFzLmRhdGEuZnJhbWUoZGF0YSR1dG0uZWFzdGluZykNCiAgeSA8LSBhcy5kYXRhLmZyYW1lKGRhdGEkdXRtLm5vcnRoaW5nKQ0KICB4eSA8LSBjKHgseSkNCiAgZGF0YS5wcm9qIDwtIFNwYXRpYWxQb2ludHNEYXRhRnJhbWUoeHksZGF0YSwgcHJvajRzdHJpbmcgPSBDUlMoIitwcm9qPXV0bSArem9uZT0xOCArZWxscHM9V0dTODQgK3VuaXRzPW0gK25vX2RlZnMiKSkNCiAgeHkgPC0gU3BhdGlhbFBvaW50cyhkYXRhLnByb2pAY29vcmRzKQ0KICBtY3Aub3V0IDwtIG1jcCh4eSwgcGVyY2VudD0xMDAsIHVub3V0PSJoYSIpDQogIG1jcC5wb2ludHMgPC0gY2JpbmQoKGRhdGEuZnJhbWUoeHkpKSxkYXRhJGluZGl2aWR1YWwubG9jYWwuaWRlbnRpZmllcikNCiAgY29sbmFtZXMobWNwLnBvaW50cykgPC0gYygieCIsInkiLCAiaWRlbnRpZmllciIpDQogIG1jcC5wb2x5IDwtIGZvcnRpZnkobWNwLm91dCwgcmVnaW9uID0gImlkIikNCiAgdW5pdHMgPC0gZ3JpZC50ZXh0KHBhc3RlKHJvdW5kKG1jcC5vdXRAZGF0YSRhcmVhLDIpLCJoYSIpLCB4PTAuODUsICB5PTAuOTUsDQogICAgICAgICAgICAgICAgICAgICBncD1ncGFyKGZvbnRmYWNlPTQsIGNvbD0id2hpdGUiLCBjZXg9MC45KSwgZHJhdyA9IEZBTFNFKQ0KICBtY3AucGxvdCA8LSBhdXRvcGxvdChyYXN0ZXJfdXRtLCBleHBhbmQgPSBUUlVFKSArIHRoZW1lX2J3KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArDQogICAgdGhlbWUocGFuZWwuYm9yZGVyID0gZWxlbWVudF9yZWN0KGNvbG91ciA9ICJibGFjayIsIGZpbGw9TkEsIHNpemU9MSkpICsNCiAgICBnZW9tX3BvbHlnb24oZGF0YT1tY3AucG9seSwgYWVzKHg9bWNwLnBvbHkkbG9uZywgeT1tY3AucG9seSRsYXQpLCBhbHBoYT0wLjgpICsNCiAgICBnZW9tX3BvaW50KGRhdGE9bWNwLnBvaW50cywgYWVzKHg9eCwgeT15KSkgKyANCiAgICBsYWJzKHg9IkVhc3RpbmcgKG0pIiwgeT0iTm9ydGhpbmcgKG0pIiwgdGl0bGU9bWNwLnBvaW50cyRpZGVudGlmaWVyKSArDQogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIiwgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBoanVzdCA9IDAuNSkpICsgDQogICAgYW5ub3RhdGlvbl9jdXN0b20odW5pdHMpDQogIG1jcC5wbG90DQp9DQoNCnBibGFwcGx5KGZpbGVzLCBtY3BfcmFzdGVyKQ0KYGBgDQoNCiMjIEtlcm5lbC1EZW5zaXR5IEVzdGltYXRpb24NCg0KYGBge3IgS0RFIHBsb3QsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGVjaG89VFJVRSwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9Nn0NCmtkZV9yYXN0ZXIgPC0gZnVuY3Rpb24oZmlsZW5hbWUpew0KICBkYXRhIDwtIHJlYWQuY3N2KGZpbGUgPSBmaWxlbmFtZSkNCiAgeCA8LSBhcy5kYXRhLmZyYW1lKGRhdGEkdXRtLmVhc3RpbmcpDQogIHkgPC0gYXMuZGF0YS5mcmFtZShkYXRhJHV0bS5ub3J0aGluZykNCiAgeHkgPC0gYyh4LHkpDQogIGRhdGEucHJvaiA8LSBTcGF0aWFsUG9pbnRzRGF0YUZyYW1lKHh5LGRhdGEsIHByb2o0c3RyaW5nID0gQ1JTKCIrcHJvaj11dG0gK3pvbmU9MTggK2VsbHBzPVdHUzg0ICt1bml0cz1tICtub19kZWZzIikpDQogIHh5IDwtIFNwYXRpYWxQb2ludHMoZGF0YS5wcm9qQGNvb3JkcykNCiAga2RlPC1rZXJuZWxVRCh4eSwgaD0iaHJlZiIsIGtlcm49ImJpdm5vcm0iLCBncmlkPTEwMCkNCiAgdmVyIDwtIGdldHZlcnRpY2VzaHIoa2RlLCA5NSkNCiAga2RlLnBvaW50cyA8LSBjYmluZCgoZGF0YS5mcmFtZShkYXRhLnByb2pAY29vcmRzKSksZGF0YSRpbmRpdmlkdWFsLmxvY2FsLmlkZW50aWZpZXIpDQogIGNvbG5hbWVzKGtkZS5wb2ludHMpIDwtIGMoIngiLCJ5IiwiaWRlbnRpZmllciIpDQogIGtkZS5wb2x5IDwtIGZvcnRpZnkodmVyLCByZWdpb24gPSAiaWQiKQ0KICB1bml0cyA8LSBncmlkLnRleHQocGFzdGUocm91bmQodmVyJGFyZWEsMiksIiBoYSIpLCB4PTAuODUsICB5PTAuOTUsDQogICAgICAgICAgICAgICAgICAgICBncD1ncGFyKGZvbnRmYWNlPTQsIGNvbD0id2hpdGUiLCBjZXg9MC45KSwgZHJhdyA9IEZBTFNFKQ0KICBrZGUucGxvdCA8LSBhdXRvcGxvdChyYXN0ZXJfdXRtLCBleHBhbmQgPSBUUlVFKSArIHRoZW1lX2J3KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArDQogICAgdGhlbWUocGFuZWwuYm9yZGVyID0gZWxlbWVudF9yZWN0KGNvbG91ciA9ICJibGFjayIsIGZpbGw9TkEsIHNpemU9MSkpICsNCiAgICBnZW9tX3BvbHlnb24oZGF0YT1rZGUucG9seSwgYWVzKHg9a2RlLnBvbHkkbG9uZywgeT1rZGUucG9seSRsYXQpLCBhbHBoYSA9IDAuOCkgKw0KICAgIGdlb21fcG9pbnQoZGF0YT1rZGUucG9pbnRzLCBhZXMoeD14LCB5PXkpKSArDQogICAgbGFicyh4PSJFYXN0aW5nIChtKSIsIHk9Ik5vcnRoaW5nIChtKSIsIHRpdGxlPWtkZS5wb2ludHMkaWRlbnRpZmllcikgKw0KICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIsIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgaGp1c3QgPSAwLjUpKSArIA0KICAgIGFubm90YXRpb25fY3VzdG9tKHVuaXRzKQ0KICBrZGUucGxvdA0KfQ0KDQpwYmxhcHBseShmaWxlcywga2RlX3Jhc3RlcikNCmBgYA0KDQojIyMgQnJvd25pYW4gQnJpZGdlIE1vdmVtZW50DQoNCk5vIEx1Y2sgZm9yIE5vdzsNCg0KY291bGRuJ3QgZ2V0IGNyb3AgdG8gcnVuIG1lc3NhZ2Ugd2FzOiAiRXJyb3IgaW4geEBjb29yZHNbaSwgLCBkcm9wID0gRkFMU0VdIDogc3Vic2NyaXB0IG91dCBvZiBib3VuZHMiDQoNCkhvd2V2ZXIsIEkgbGVhcm5lZCB0aGF0IGluIGV4Y2VsIHlvdSBuZWVkIHRvIHNldCB0aGUgZm9ybWF0IG9mIHRoZSBjb2x1bW4gdG8gY3VzdHVtIGFuZCB0eXBlIGluICJ5eXl5LW1tLWRkIGg6bW06c3MiIGFuZCBpdCB3aWxsIGNvcnJlY3QgdGhlIGVudGlyZSBjb2x1bW4gdG8gdGhhdCBmb3JtYXQuIFRoaXMgbWF5IGJlIHZlcnkgbXVjaCBhIG5vIGJyYWluZXIuDQoNCmBgYHtyIGJiIHBsb3QsIGV2YWw9RkFMU0UsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTYsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQpBIDwtIHJlYWQuY3N2KCJBbHBoYSAuY3N2IikNCmRhdGUgPC0gYXMuUE9TSVhjdChzdHJwdGltZShhcy5jaGFyYWN0ZXIoQSR0aW1lc3RhbXApLCIlWS0lbS0lZCAlSDolTTolUyIsIHR6PSJBc2lhL0Jhbmdrb2siKSkNCkEkZGF0ZSA8LSBkYXRlDQpBLnJlbG9jIDwtIGNiaW5kLmRhdGEuZnJhbWUoQSR1dG0uZWFzdGluZywgQSR1dG0ubm9ydGhpbmcsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzLnZlY3RvcihBJGluZGl2aWR1YWwubG9jYWwuaWRlbnRpZmllciksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzLlBPU0lYY3QoZGF0ZSkpDQpjb2xuYW1lcyhBLnJlbG9jKSA8LSBjKCJ4IiwieSIsImlkIiwiZGF0ZSIpDQp0cmFqZWN0b3J5IDwtIGFzLmx0cmFqKEEucmVsb2MsIGRhdGU9ZGF0ZSwgaWQ9IkFscGhhIikNCnNpZzEgPC0gbGlrZXIodHJhamVjdG9yeSwgc2lnMiA9IDU4LCByYW5nZXNpZzEgPSBjKDAsIDUpLCBwbG90aXQgPSBGQUxTRSkNCm9waGEudHJhaiA8LSBrZXJuZWxiYih0cmFqZWN0b3J5LCBzaWcxID0gLjc5MDgsIHNpZzIgPSA1OCwgZ3JpZCA9IDEwMCkNCmJiX3ZlciA8LSBnZXR2ZXJ0aWNlc2hyKG9waGEudHJhaiwgOTUpDQpiYl9wb2x5IDwtIGZvcnRpZnkoYmJfdmVyLCByZWdpb24gPSAiaWQiLCANCiAgICAgICAgICAgICAgICAgICBwcm9qNHN0cmluZyA9IENSUygiK3Byb2o9dXRtICt6b25lPTE4Kw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsbHBzPVdHUzg0ICt1bml0cz1tICtub19kZWZzIikpDQpjb2xuYW1lcyhiYl9wb2x5KSA8LSBjKCJ4IiwieSIsIm9yZGVyIiwiaG9sZSIsInBpZWNlIiwiaWQiLCJncm91cCIpDQpiYl9pbWFnZSA8LSBjcm9wKG9waGEudHJhaiwgYmJfdmVyLCANCiAgICAgICAgICAgICAgICAgcHJvajRzdHJpbmcgPSBDUlMoIitwcm9qPXV0bSArem9uZT00NyArDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsbHBzPVdHUzg0ICt1bml0cz1tICtub19kZWZzIikpDQpiYl91bml0cyA8LSBncmlkLnRleHQocGFzdGUocm91bmQoYmJfdmVyJGFyZWEsMiksIiBoYSIpLCB4PTAuODUsICB5PTAuOTUsDQogICAgICAgICAgICAgICAgICAgZ3A9Z3Bhcihmb250ZmFjZT00LCBjb2w9IndoaXRlIiwgY2V4PTAuOSksIGRyYXcgPSBGQUxTRSkNCmJiLnBsb3QgPC0gYXV0b3Bsb3QocmFzdGVyX3V0bSwgZXhwYW5kID0gVFJVRSkgKyB0aGVtZV9idygpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgKw0KICB0aGVtZShwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoY29sb3VyID0gImJsYWNrIiwgZmlsbD1OQSwgc2l6ZT0xKSkgKw0KICBnZW9tX3RpbGUoZGF0YT1iYl9pbWFnZSwgDQogICAgICAgICAgICBhZXMoeD1iYl9pbWFnZUBjb29yZHNbLDFdLCB5PWJiX2ltYWdlQGNvb3Jkc1ssMl0sDQogICAgICAgICAgICBmaWxsID0gYmJfaW1hZ2VAZGF0YSR1ZCkpICsNCiAgZ2VvbV9wb2x5Z29uKGRhdGE9YmJfcG9seSwgYWVzKHg9eCwgeT15LCBncm91cCA9IGdyb3VwKSwgY29sb3IgPSAiYmxhY2siLCBmaWxsID0gTkEpICsNCiAgc2NhbGVfZmlsbF92aXJpZGlzX2Mob3B0aW9uID0gImluZmVybm8iKSArIGFubm90YXRpb25fY3VzdG9tKGJiX3VuaXRzKSArDQogIGxhYnMoeD0iRWFzdGluZyAobSkiLCB5PSJOb3J0aGluZyAobSkiLCB0aXRsZT0iT1BIQTEiKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIsIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgaGp1c3QgPSAwLjUpKQ0KYmIucGxvdA0KYGBgDQojIyBBbmltYXRlIFRyYWplY3RvcnkgRGF0YQ0KDQpIZXJlIGlzIG15IGF0dGVtcHQgYXQgY3JlYXRpbmcgYW4gYW5pbWF0aW9uIG9mIHRoZSBpbmRpdmlkdWFsICJBbHBoYSIncyBtb3ZlbWVudCBmcm9tIEFwcmlsIHRvIEp1bHkgaW4gMjAwMSBpbiBBbGJhbnksIE5ZLCBVU0EuIERhdGEgd2FzIGNvbGxlY3RlZCBieSByYWRpbyB0ZWxlbWV0cnkuDQoNCmBgYHtyIG1vdmUsIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgcmVzdWx0cz0naGlkZSd9DQpBLm1vdmUgPC0gbW92ZSh4PUEkbG9jYXRpb24ubG9uZywgDQogICAgICAgICAgICAgeT1BJGxvY2F0aW9uLmxhdCwgDQogICAgICAgICAgICAgdGltZT1hcy5QT1NJWGN0KEEkdGltZXN0YW1wLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0PSIlWS0lbS0lZCAlSDolTTolUyIsIHR6PSJBc2lhL0Jhbmdrb2siKSwgDQogICAgICAgICAgICAgcHJvaj1DUlMoIitwcm9qPWxvbmdsYXQgK2VsbHBzPVdHUzg0ICtkYXR1bT1XR1M4NCIpLA0KICAgICAgICAgICAgIGRhdGE9QSwgYW5pbWFsPUEkaW5kaXZpZHVhbC5sb2NhbC5pZGVudGlmaWVyLCANCiAgICAgICAgICAgICBzZW5zb3I9QSRzZW5zb3IudHlwZSkNCg0KbW92ZW1lbnQgPC0gYWxpZ25fbW92ZShBLm1vdmUsIHJlcyA9ICJtYXgiLCBkaWdpdCA9IDAsIHVuaXQgPSAic2VjcyIpDQoNCmZyYW1lcyA8LSBmcmFtZXNfc3BhdGlhbChtb3ZlbWVudCwgcGF0aF9jb2xvdXJzID0gIm9yYW5nZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgbWFwX3NlcnZpY2UgPSAib3NtIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICBhbHBoYSA9IDAuNSkgJT4lIA0KICBhZGRfbGFiZWxzKHggPSAiTG9uZ2l0dWRlIiwgeSA9ICJMYXRpdHVkZSIpICU+JQ0KICBhZGRfbm9ydGhhcnJvdygpICU+JSANCiAgYWRkX3NjYWxlYmFyKCkgJT4lIA0KICBhZGRfdGltZXN0YW1wcyhtb3ZlbWVudCwgdHlwZSA9ICJsYWJlbCIpICU+JSANCiAgYWRkX3Byb2dyZXNzKCkNCg0KYW5pbWF0ZV9mcmFtZXMoZnJhbWVzLCBmcHMgPSA1LCBvdmVyd3JpdGUgPSBUUlVFLA0KICAgICAgICAgICAgICAgb3V0X2ZpbGUgPSAiLi9tb3ZlVmlzLTVmcHMuZ2lmIikNCmBgYA0KIVtdKC4vbW92ZVZpcy01ZnBzLmdpZiAiUmVsb2NhdGlvbiBBbmltYXRpb24gZm9yIEFscGhhIikNCg==